/*
 * @Date: 2022-02-11 16:28:30
 * @LastEditors: tich425
 * @LastEditTime: 2022-02-12 17:34:46
 * @FilePath: \TodoList\service\user.go
 * @Description: user 处理
 */
package service

import (
	"log"
	"todo-list/global"
	"todo-list/model"
	"todo-list/res"
	"todo-list/utils"

	"github.com/gin-gonic/gin"
	"golang.org/x/crypto/bcrypt"
)

/**
 * @description: 发送验证码
 * @param {string} email
 * @param {*gin.Context} c
 */
func SendEmailCode(email string, c *gin.Context) {

	if utils.IsEmailExist(email) {
		res.FailWithMessage(res.ParamErr, "邮箱已存在", c)
		return
	}

	if utils.GenerateCode(email) {
		res.OkWithMessage("发送成功", c)
	} else {
		res.FailWithMessage(res.ParamErr, "发送失败", c)
	}
}

/**
 * @description: 用户注册处理
 * @param {model.Regist} r
 * @param {*gin.Context} c
 */
func Regist(r model.Regist, c *gin.Context) {
	// 判断用户名是否存在
	if utils.IsUsernameExist(r.Username) {
		res.FailWithMessage(res.ParamErr, "用户名已存在", c)
		return
	}
	// 判断邮箱是否存在
	if utils.IsEmailExist(r.Email) {
		res.FailWithMessage(res.ParamErr, "邮箱已存在", c)
		return
	}

	// 判断验证码是否正确
	if !utils.VerifyCode(r.Email, r.VerifyCode) {
		res.FailWithMessage(res.ParamErr, "验证码错误", c)
		return
	}

	// 密码加密
	hashPassword, err := bcrypt.GenerateFromPassword([]byte(r.Password), bcrypt.DefaultCost)
	if err != nil {
		log.Print("Password hash error:", err)
		res.FailWithMessage(res.HashErr, "密码加密失败, 请勿使用违禁字符", c)
		return
	}
	r.Password = string(hashPassword)

	// 结构体转换
	u := model.User{
		Username: r.Username,
		Password: r.Password,
		Email:    r.Email,
	}

	// 保存到数据库
	global.MYSQL_DB.Create(&u)

	// 返回信息
	if u.ID > 0 {
		res.OkWithMessage("注册成功", c)
	} else {
		res.FailWithMessage(res.ParamErr, "注册失败, 请稍后尝试", c)
	}
}

func Login(l model.Login, c *gin.Context) {
	// 验证用户存在
	var u model.User
	if err := global.MYSQL_DB.Where("username = ?", l.Username).First(&u).Error; err != nil {
		if err := global.MYSQL_DB.Where("email = ?", l.Username).First(&u).Error; err != nil {
			res.FailWithMessage(res.ParamErr, "用户名或密码错误", c)
			return
		}
	}

	// 密码验证
	if err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(l.Password)); err != nil {
		res.FailWithMessage(res.ParamErr, "用户名或密码错误", c)
		return
	}

	// 生成 Token
	token, err := utils.ReleaseToken(u)
	if err != nil {
		log.Print("Token generate error:", err)
		res.FailWithMessage(res.TokenErr, "Token分发错误", c)
		return
	}

	// 数据转换
	ud := model.UserDto{
		ID:       u.ID,
		Username: u.Username,
		Email:    u.Email,
		IsSuper:  u.IsSuper,
		// Avatar:   u.Avatar,
	}

	// 成功响应
	res.OkWithDetailed(gin.H{"user": ud, "token": token}, "登录成功", c)
}

/**
 * @description: 上传头像处理
 * @param {uint} uid
 * @param {*multipart.FileHeader} f
 * @param {*gin.Context} c
 */
// func UploadImg(uid uint, f *multipart.FileHeader, c *gin.Context) {
// 	// 创建结构体实例
// 	var u model.User
// 	// 获取用户信息
// 	if err := global.MYSQL_DB.Where("ID = ?", uid).First(&u).Error; err != nil {
// 		res.FailWithMessage(res.ParamErr, "用户名尚未登录", c)
// 		return
// 	}

// 	now := time.Now()
// 	fileType := "other"
// 	// 判断后缀为图片的文件
// 	fileExt := filepath.Ext(f.Filename)
// 	if fileExt == ".jpg" || fileExt == ".png" || fileExt == ".gif" || fileExt == ".jpeg" {
// 		fileType = "img"
// 	}
// 	fileDir := fmt.Sprintf("public/upload/%s/%d/%d/%d", fileType, now.Year(), now.Month(), now.Day())
// 	err := os.MkdirAll(fileDir, os.ModePerm)
// 	if err != nil {
// 		res.FailWithMessage(res.ParamErr, "", c)
// 		return
// 	}

// 	timeStamp := time.Now().Unix()
// 	fileName := fmt.Sprintf("%d-%s", timeStamp, f.Filename)
// 	filePathStr := filepath.Join(fileDir, fileName)

// 	c.SaveUploadedFile(f, filePathStr)

// 	// 返回信息
// 	res.OkWithMessage("上传成功！", c)
// }
